package Domain;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author ParaSait
 */
public class Utils {
    
    /**
     * Computes the SHA-1 hash of a byte array
     *
     * @param array A byte array
     * @return String with SHA-1 hash of the byte array
     */
    public static String byteArrayToHex(byte[] array) {
        StringBuilder sb = new StringBuilder();
        for (byte b : array) {
            sb.append(String.format("%02x", b & 0xff));
        }
        return sb.toString();
    }

    /**
     * Computes the SHA-1 hash of a file
     *
     * @param file The file
     * @return The array of bytes for the resulting hash value.
     */
    public static byte[] calculateFileHash(File file) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA1");
            FileInputStream stream = new FileInputStream(file);
            byte[] dataBytes = new byte[1024];
            int nread = 0;

            while ((nread = stream.read(dataBytes)) != -1) {
                md.update(dataBytes, 0, nread);
            }
            stream.close();

            byte[] mdbytes = md.digest();
            return mdbytes;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static List<File> getFileList(List<File> fileList, File root, File subdir) {
        File[] fileArray = subdir.listFiles();
        for (File file : fileArray) {
            if (!file.isDirectory()) {
                fileList.add(file);
            } else {
                getFileList(fileList, root, file);
            }
        }
        return fileList;
    }

    /**
     * Return a list with all the files (also in subdirectories) starting from the root param
     * @param root The directory from where you want to start
     * @return The list with file objects
     */
    public static List<File> getFileList(File root) {
        return getFileList(new ArrayList<File>(), root, root);
    }

     /**
     * Deletes a file and all the parent folder of this file that will be empty after the file has been deleted. <br />
     * Method is called recursively. This will stop when the root directory is reached. <br />
     * For example: /root/folder1/folder2/test.txt <br />
     * -> text.txt is deleted <br />
     * -> folder 2 is empty -> delete folder 2 <br />
     * -> folder 1 is NOT empty -> DON't delete folder 1 -> return
     *
     * @param path The path of the file to delete
     * @param root The root directory, used to check when to stop the recursion
     * @throws IOException If there is a problem reading the file
     */
    public static void deleteFileAndItsEmptyParentFolders(Path path, String root) throws IOException {
        if (path == null || path.endsWith(root)) {
            return;
        }
        if (Files.isRegularFile(path)) {
            Files.deleteIfExists(path);
        } else if (Files.isDirectory(path)) {
            if (new File(path.toUri()).list().length == 0) {
                Files.delete(path);
            } else {
                return;
            }
        }
        deleteFileAndItsEmptyParentFolders(path.getParent(), root);
    }
    
    // If the file is a folder
    // -> Delete all children
    // -> Delete folder
    // If file is a file
    // -> Delete file
    public static void deleteFile(Path path, String root) throws IOException {
        if (path == null || path.endsWith(root)) {
            return;
        }
        if (Files.isDirectory(path)) {
            String[] children = new File(path.toUri()).list();
            if(children.length != 0) {
                for (int i = 0; i < children.length; i++) {
                    String childPath = path + "\\" + children[i];
                    deleteFile(Paths.get(childPath), root);
                }
            }
            Files.deleteIfExists(path);
        } else {
            Files.deleteIfExists(path);
        }
    }

}